#!/usr/bin/env python

import sys

from HTMLParser import HTMLParser
from data.templates import templates

class ODPType ( object ):
	def __init__ ( self, attrs = None ):
		self.nodes = []
		self.kind = "generic"

	def add ( self, txt ):
		txt = txt.strip ()
		if not txt: return
		self.nodes.append ( txt )

	def is_empty ( self ):
		return not len ( self.nodes )

	def __repr__ ( self ):
		res = []

		res.append ( templates [ self.kind + '-start' ] )
		for node in self.nodes:
			if isinstance ( node, ODPType ):
				res.append ( repr ( node ) )
			else:
				res.append ( templates [ 'p-start' ] )
				res.append ( node )
				res.append ( templates [ 'p-end' ] )

		res.append ( templates [ self.kind + '-end' ] )

		return ''.join ( res )

class ODPRoot ( ODPType ):
	def __init__ ( self, attrs = None ):
		super ( ODPRoot, self ).__init__ ( attrs )
		self.kind = "root"

class ODPText ( ODPType ):
	def __init__ ( self, attrs = None ):
		super ( ODPText, self ).__init__ ( attrs )
		self.kind = "textbox"

		if attrs and "empty" in attrs:
			self.nodes.append ( "" )


class ODPList ( ODPType ):
	def __init__ ( self, attrs = None ):
		super ( ODPList, self ).__init__ ( attrs )
		self.kind = "list"

class ODPListItem ( ODPType ):
	def __init__ ( self, attrs = None ):
		super ( ODPListItem, self ).__init__ ( attrs )
		self.kind = "list-item"

class ODPCode ( ODPType ):
	def __init__ ( self, attrs = None ):
		super ( ODPCode, self ).__init__ ( attrs )
		self.kind = "code"

class ODPSlide ( object ):
	def __init__ ( self, slide_number, title ):
		self.slide_number = slide_number
		self.title = title
		self.obj_stack = []
		self.curr_obj = None

		self._create ( ODPRoot, None )
		self._root = self.curr_obj

	def data ( self, txt ):
		if self.curr_obj == self._root:
			self.text_start ( None )
			
		self.curr_obj.add ( txt )

	def ul_start ( self, attrs ):
		self._create ( ODPList, attrs )

	def text_start ( self, attrs ):
		self._create ( ODPText, attrs )

	def li_start ( self, attrs ):
		self._create ( ODPListItem, attrs )

	def code_start ( self, attrs ):
		self._create ( ODPCode, attrs )

	def tag_end ( self, attrs = None ):
		self.obj_stack.pop ()
		self.curr_obj = self.obj_stack [ -1 ]

		#print "- CURR OBJ: %s" % self.curr_obj.kind

	def _create ( self, obj_type, attrs ):
		obj = obj_type ( attrs )

		if self.curr_obj: 
			#print "APPEND: %s to %s" % ( obj.kind, self.curr_obj.kind )
			self.curr_obj.nodes.append ( obj )

		self.curr_obj = obj
		self.obj_stack.append ( obj )

		#print "+ CURR OBJ: %s" % self.curr_obj.kind

	def __repr__ ( self ):
		res = repr  ( self._root.nodes [ 0 ] )
		return res



class ODPGenerator ( object ):
	def __init__ ( self ):
		self.slides = []
		self.slide_number = 0
		self.curr_slide = None

		self._pres_started = False
		self._slide_open   = False

		self._tag_stack = []
		
	def data ( self, txt ):
		self._tag_print ( "p", "start", {} )
		print txt
		self._tag_print ( "p", "end", {} )

	def generate ( self ):
		return ''

	def slide_start ( self, attrs ):
		if self._slide_open:
			self.slide_end ()

		self.slide_number += 1

		if self.slide_number == 1:
			self._presentation_start ()

		attrs [ 'SLIDE_TITLE' ] = attrs.get ( "title", "missing slide title for slide: %d" % self.slide_number )
		attrs [ 'SLIDE_NUMBER' ] = self.slide_number
		
		self._tag_print ( "slide", "start", attrs )
		
	def slide_end ( self, attrs ):
		self._slide_open = False
		attrs [ 'SLIDE_NUMBER' ] = self.slide_number
		self._tag_print ( "slide", "end", attrs )

	def tag_start ( self, name, attrs ):
		sys.stderr.write ( "----- START: %s\n" % name )
		self._tag_print ( name, "start", attrs )

	def tag_end ( self, name, attrs ):
		self._tag_print ( name, "end", attrs )

	def _tag_print ( self, name, mode, attrs ):
		tmp = templates.get ( "%s-%s" % ( name, mode ), "" )
		if not tmp: return

		#print name, mode, attrs
		print tmp % attrs

	def _presentation_start ( self ):
		"""
		Dumps the first part of content.xml
		"""
		if self._pres_started: return

		self._pres_stared = True
		print templates [ 'presentation-start' ]
		
		

# create a subclass and override the handler methods
class HTML2ODP (HTMLParser):
	odp_gen = ODPGenerator ()

	actions = {
		"div:0" :  odp_gen.slide_start,
		"div:1"	:  odp_gen.slide_end,
	}

	def _execute ( self, tag, mode, attrs = None ):
		name = tag + ":" + mode
		
		dct = {}
		if attrs:
			for el in attrs:
				dct [ el [ 0 ] ] = el [ 1 ]

		if name in self.actions:
			self.actions [ name ] ( dct )
		else:
			if mode == "0":
				self.odp_gen.tag_start ( tag, dct )
			else:
				self.odp_gen.tag_end ( tag, dct )

	def handle_starttag ( self, tag, attrs ):
		self._execute ( tag, "0", attrs )

	def handle_endtag ( self, tag ):
		self._execute ( tag, "1" )

	def handle_data ( self, data ):
		if not data.strip (): return

		self.odp_gen.data ( data )

# instantiate the parser and fed it some HTML
parser = HTML2ODP ()
parser.feed ( open ( "example/test.html" ).read () )
